package util;

import java.io.*;
import java.util.Vector;

import static skeleton.Board.*;

public class LibSearcher {
	static final int BLACK = skeleton.Startup.Chess_Clr_Black;
	static final int WHITE = skeleton.Startup.Chess_Clr_White;
	public Situation[] libs;
	public int num;
	static int UD = 0, LR = 1, UDLR = 2;

	public void load(String filename) {
		try {
			BufferedReader br = new BufferedReader(new FileReader(filename));
			String line = null;
			String[] ss;
			num = 0;
			Vector<Situation> libRec = new Vector<Situation>();
			while (true) {
				int count = 0;
				do {
					line = br.readLine();
					if (++count == 10 || line == null) break; //max 10 empty lines
				} while (line.length() == 0);
				if (count == 10 || line == null) break;
				ss = line.split(" ");
				int r, c;
				r = Integer.parseInt(ss[0]);
				c = Integer.parseInt(ss[1]);
				Situation situ = new Situation(r, c); 
				for (int j=0; j<r; ++j) {
					line = br.readLine();
					for (int k=0; k<c; ++k)
						if (line.charAt(k) == '0') situ.data[j][k] = BLACK;
						else if (line.charAt(k) == '1') situ.data[j][k] = WHITE;
						else if (line.charAt(k) == EMPTY) situ.data[j][k] = EMPTY;
						else {
							Lib.assertNotReached("unknown char in board.");
						}
				}
				ss = br.readLine().split(" ");
				situ.nextRow = Integer.parseInt(ss[0]);
				situ.nextCol = Integer.parseInt(ss[1]);
				libRec.add(situ);
			}
			br.close();
			num = libRec.size();
			libs = new Situation[num];
			for (int i=0; i<libs.length; ++i) {
				libs[i] = libRec.get(i);
				libs[i].show();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public Pair find(Situation s) {
		Situation[] isor = new Situation[8];
		Situation rotation = rotate(s);
		isor[0] = s;
		isor[1] = mirror(s, UD);
		isor[2] = mirror(s, LR);
		isor[3] = mirror(s, UDLR);
		isor[4] = rotation;
		isor[5] = mirror(rotation, UD);
		isor[6] = mirror(rotation, LR);
		isor[7] = mirror(rotation, UDLR);
//		for (int i=0; i<8; ++i) isor[i].show();
		
		for (int i=0; i<num; ++i) {
			for(int j = 0; j < 8; ++ j) {
				if(compare(libs[i], isor[j])) {
					Pair pair = null;
					if(j == 0) {
						pair = new Pair(libs[i].nextRow, libs[i].nextCol);
					}
					if(j == 1) {
						pair = new Pair(libs[i].rows - 1 - libs[i].nextRow, libs[i].nextCol);
					}
					if(j == 2) {
						pair = new Pair(libs[i].nextRow, libs[i].cols - 1 - libs[i].nextCol);
					}
					if(j == 3) {
						pair = new Pair(libs[i].rows - 1 - libs[i].nextRow, libs[i].cols - 1 - libs[i].nextCol);
					}
					if(j == 4) {
						pair = new Pair(libs[i].nextCol, libs[i].nextRow);
					}
					if(j == 5) {
						pair = new Pair(libs[i].nextCol, libs[i].rows - 1 - libs[i].nextRow);
					}
					if(j == 6) {
						pair = new Pair(libs[i].cols - 1 - libs[i].nextCol, libs[i].nextRow);
					}
					if(j == 7) {
						pair = new Pair(libs[i].cols - 1 - libs[i].nextCol, libs[i].rows - 1 - libs[i].nextRow);
					}
					return pair;
				}
			}
		}
		return null;
	}
	
	public boolean compare(Situation a, Situation b) {
		if(a.rows != b.rows || a.cols != b.cols)
			return false;
		for(int i = 0 ;i < a.rows; ++ i)
			for(int j = 0; j < a.cols; ++ j)
				if(a.data[i][j] != b.data[i][j]) {
					return false;
				}
		return true;
	}
	
	public Situation rotate(Situation s) {
		int [][] data = new int[s.cols][s.rows];
		for(int i = 0; i < s.rows; ++ i)
			for(int j = 0; j < s.cols; ++ j) {
				data[j][i] = s.data[i][j];
			}
		Situation newS = new Situation(s.cols, s.rows);
		newS.data = data;
		return newS;
	}
	
	public Situation mirror(Situation s, int type) {
		Situation ss = new Situation(s.rows, s.cols);
		if(type == UD) {
			for(int i = 0; i < s.rows; ++ i) {
				for(int j = 0; j < s.cols; ++ j) {
					ss.data[i][j] = s.data[s.rows -1 - i][j];
//					ss.data[s.rows -1 - i][j] = s.data[i][j];
				}
			}
		}
		else if(type == LR) {
			for(int j = 0;  j < s.cols ;++ j) {
				for(int i = 0; i < s.rows; ++ i) {
					ss.data[i][j] = s.data[i][s.cols - 1- j];
//					s.data[i][s.cols - 1 - j] = s.data[i][j];
				}
			}
		}
		else if(type == UDLR) {
			for(int i = 0; i < s.rows; ++ i) {
				for(int j = 0; j < s.cols; ++ j) {
					ss.data[i][j] = s.data[s.rows -1 - i][s.cols - 1- j];
//					s.data[s.rows -1 - i][s.cols - 1- j] = s.data[i][j];
				}
			}
		}
		return ss;
	}
}
